package com.xh.bussiness.resource.service.impl;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.List;

import com.google.common.io.Files;
import com.xh.bussiness.course.model.CourseIndex;
import com.xh.bussiness.course.model.PrepareLesson;
import com.xh.bussiness.course.service.ICourseIndexService;
import com.xh.bussiness.course.service.IPrepareLessonService;
import com.xh.bussiness.resource.bean.request.MaterialCourseIndexRequest;
import com.xh.bussiness.resource.bean.request.MaterialSaveRequest;
import com.xh.bussiness.resource.model.MaterialChapter;
import com.xh.bussiness.resource.model.MaterialCourseIndex;
import com.xh.bussiness.resource.model.MaterialPrepare;
import com.xh.bussiness.resource.service.IMaterialChapterService;
import com.xh.bussiness.resource.service.IMaterialCourseIndexService;
import com.xh.bussiness.resource.service.IMaterialPrepareService;
import com.xh.bussiness.resource.util.FfmpegUtils;
import com.xh.bussiness.resource.util.MaterialUtils;
import com.xh.bussiness.resource.util.web365Utils;
import com.xh.bussiness.system.model.FileList;
import com.xh.bussiness.tiku.model.BookChapter;
import com.xh.bussiness.tiku.service.IBookChapterService;
import com.xh.core.util.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xh.bussiness.resource.bean.request.MaterialRequest;
import com.xh.bussiness.resource.dao.MaterialMapper;
import com.xh.bussiness.resource.model.Material;
import com.xh.bussiness.resource.service.IMaterialService;
import com.xh.core.bean.XhPage;
import com.xh.core.service.impl.BaseServiceImpl;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <p>
 * 资料 服务实现类
 * </p>
 *
 * @author JQM
 * @since 2019-08-27
 */
@Service
public class MaterialServiceImpl extends BaseServiceImpl<MaterialMapper, Material> implements IMaterialService {

    @Autowired
    private IMaterialCourseIndexService materialCourseIndexService;
    @Autowired
    private IMaterialPrepareService materialPrepareService;
    @Autowired
    private IMaterialChapterService materialChapterService;
    @Autowired
    private ICourseIndexService courseIndexService;
    @Autowired
    private IPrepareLessonService prepareLessonService;
    @Autowired
    private IBookChapterService bookChapterService;


    @Override
    public XhPage<Material> queryMaterialPage(XhPage page, MaterialRequest bean) {
        bean.setCreatorId(UserUtils.getCurrentUserId());
        return this.dao.queryByPage(page,bean);
    }

    @Override
    public List queryMaterial(MaterialRequest bean) {
        QueryWrapper qw=new QueryWrapper<Material>();
        //拼装条件
        qw=prepareParams(bean, qw);

        return this.dao.selectList(qw);
    }

    @Override
    public List queryMaterialByCourseIndexId(MaterialCourseIndexRequest bean) {
        List<MaterialCourseIndex>  materialRelList= materialCourseIndexService.query(bean);
        String[] mateIds = materialRelList.stream().map(MaterialCourseIndex::getMaterialId).toArray(String[]::new);
        if(mateIds.length == 0){
            return new ArrayList();
        }
        MaterialRequest  mr = new MaterialRequest();
        mr.setIds(mateIds);
        List<Material> materials = queryMaterial(mr);
        return materials;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchSave(MaterialSaveRequest materials,HttpServletRequest request) {

        String rootPath = request.getSession().getServletContext().getRealPath("/");
        String relativePath="/upload"+"/";
        String customPath=request.getParameter("path");
        if(!StringUtils.isEmpty(customPath)){
            relativePath+=customPath+"/";
        }
        Date now =new Date();
         relativePath+= DateUtils.format(now,"yyyyMM")+"/";

        List<FileList> fileList = materials.getFileList();
        for (FileList file : fileList) {
            List<String> chapterIds = materials.getChapterId();


            String picture = getFile2Png(file,rootPath,relativePath);


//            String imgs = getFile2Png(file, rootPath,relativePath);
//            BufferedImage sourceImg= null;
//            int width = 0;
//            int height = 0;
//            try {
//                String picture;
//                if(file.getExt().equals("png") || file.getExt().equals("jpg") || file.getExt().equals("jpeg")){
//                    picture = rootPath + file.getFilePath();
//                }else{
//                    picture = rootPath + imgs.split(",")[0];
//                }
//
//                sourceImg = ImageIO.read(new FileInputStream(new File(picture)));
//                /**
//                 * 生成缩略图
//                 * 需设置图片地址，长宽比例
//                 */
////                String inpath = rootPath + picture;
////                String outpath = relativePath + System.currentTimeMillis() + ".jpg";
////                ImageUtil.getZoomImg(inpath, rootPath + outpath,217,190);
//
//
//                if(null != sourceImg){
//                    width = sourceImg.getWidth();
//                    height = sourceImg.getHeight();
//                }
//
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
            Material material = new Material();
            material.setFileName(Files.getNameWithoutExtension(file.getOriFilename()));
            material.setExt(file.getExt());
            material.setFilePath(file.getFilePath());
            material.setSize(file.getFileSize());
            material.setBookId(materials.getBookId());
            material.setSubject(materials.getSubject());
            material.setVersion(materials.getVersion());
            material.setIsPublic(materials.getIsPublic());
            material.setImgPath(picture);
            if(materials.getType() != null) {
                material.setType(materials.getType());
            } else {
                material.setType(getType(file.getExt()));
            }
            material.setMediaType(materials.getMediaType());
            this.dao.insert(material);

            if(!CollectionUtils.isEmpty(chapterIds)){
                for (String chapterId : chapterIds) {
                    MaterialChapter materialChapter = new MaterialChapter();
                    materialChapter.setMaterialId(material.getId());
                    materialChapter.setChapterId(chapterId);
                    materialChapterService.insert(materialChapter);
                }
            }


        }

        return true;
    }

    private Integer getType(String ext){
        switch (ext){
            case "ppt":
            case "pptx":
                return 1;
                // 讲义
            case "pdf":
            case "doc":
            case "docx":
                return 2;
            case "mp3":
                return 4;
            case "mp4":
                return 3;
            default:
                return 4;

        }
    }


    private String getFile2Png(FileList file, String rootPath,String relativePath) {

        if(file == null || file.getExt() == null) {
            return null;
        }

//        if(file.getExt().equals("doc")|| file.getExt().equals("docx")){
//             return OfficeUtils.word2png(rootPath,file.getFilePath(), relativePath,null);
//        }
//        else if(file.getExt().equals("ppt")|| file.getExt().equals("pptx")){
//            File fileDir = new File(rootPath + relativePath);
//            if(!fileDir.exists()){
//                fileDir.mkdirs();
//            }
//            String newFilename= FileUtils.randomRenameFilename(file.getOriFilename());
//            return  OfficeUtils.ppt2png(rootPath ,file.getFilePath(),relativePath+newFilename+".pdf",relativePath);
//        }
//        else if(file.getExt().equals("pdf")){
//            return  OfficeUtils.pdf2jpg(rootPath,file.getFilePath(),relativePath);
//        }
        if("mp3".equals(file.getExt())){
            return null;
        }

        String fileName = FileUtils.createRandomFilename();
        if(file.getExt().equals("mp4")){
            String filePath = relativePath + fileName + ".png";
            relativePath = relativePath.substring(0,relativePath.length()-1);
            String fileCover = FfmpegUtils.screenshot(rootPath+file.getFilePath(),"00:00:03",rootPath + relativePath,fileName);
//            String outPath =  relativePath + File.separator +FileUtils.createRandomFilename() +".png";
//            ImageUtil.getZoomImg(fileCover, rootPath + outPath,null,null);
            return filePath;
        }else if("jpg".equals(file.getExt()) || "png".equals(file.getExt()) || "jpeg".equals(file.getExt())){
//            File fileDir = new File(rootPath + relativePath);
//            if(!fileDir.exists()){
//                fileDir.mkdir();
//            }
//            String outPath =  relativePath + fileName +".png";
//            ImageUtil.getZoomImg(rootPath + file.getFilePath(), rootPath + outPath,null,null);
//            return outPath;
            return file.getFilePath();
        }
        else {
            try {
                web365Utils.downLoadFromUrl(file.getFilePath(), fileName + ".png", rootPath + relativePath);
                return relativePath + fileName + ".png";
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveUserMaterial(MaterialSaveRequest materials,HttpServletRequest request) {
        String rootPath = request.getSession().getServletContext().getRealPath("/");
        String relativePath="/upload"+"/";
        String customPath=request.getParameter("path");
        if(!StringUtils.isEmpty(customPath)){
            relativePath+=customPath+"/";
        }
        Date now =new Date();
        relativePath+= DateUtils.format(now,"yyyyMM")+"/";

        //保存备课数据
        CourseIndex lesson = courseIndexService.getById(materials.getCourseIndexId());
        String currentUserId = request.getHeader("userId");
        PrepareLesson prepareLesson = prepareLessonService.queryByUserId(currentUserId, lesson.getCourseId(), materials.getCourseIndexId());
        if (prepareLesson == null) {
            prepareLesson = new PrepareLesson();
            prepareLesson.setCourseId(lesson.getCourseId());
            prepareLesson.setCourseIndex(materials.getCourseIndexId());
            prepareLesson.setCheckStatus(0);

            prepareLessonService.insert(prepareLesson);
        }

        List<FileList> fileList = materials.getFileList();
        for (FileList file : fileList) {
            String picture = getFile2Png(file,rootPath,relativePath);
            Material material = new Material();
            material.setFileName(Files.getNameWithoutExtension(file.getOriFilename()));
            material.setExt(file.getExt());
            material.setFilePath(file.getFilePath());
            material.setSize(file.getFileSize());
            material.setIsPublic(materials.getIsPublic());
            if(materials.getType() != null) {
                material.setType(materials.getType());
            } else {
                material.setType(getType(file.getExt()));
            }
            material.setMediaType(materials.getMediaType());
            material.setImgPath(picture);
            this.dao.insert(material);

            if (materials.getType().equals(5)) {
                //标准教案
                prepareLesson.setTeachPlan(1);
            } else if (materials.getType().equals(3)) {
                //说课文件
                prepareLesson.setReviewVideo(1);
            }
            prepareLessonService.update(prepareLesson);

            MaterialPrepare materialPrepare = new MaterialPrepare();
            materialPrepare.setPrepareLessonId(prepareLesson.getId());
            materialPrepare.setCourseId(lesson.getCourseId());
            materialPrepare.setCourseIndexId(materials.getCourseIndexId());
            materialPrepare.setMaterialId(material.getId());
            materialPrepareService.insert(materialPrepare);
        }

        return true;
    }

    @Override
    public Map<String,Long> queryCountByType(MaterialRequest bean) {
        bean.setCreatorId(UserUtils.getCurrentUserId());
        Map<String,Long> result = new HashMap<>();
        result.put("courseWareCount",0L);
        result.put("handoutCount",0L);
        result.put("mediaCount",0L);
        result.put("otherCount",0L);
        result.put("teachplanCount",0L);
        result.put("multimediaCount",0L);
        List<Map<String,Object>> maps = this.dao.queryCountByType(bean);

        for(Map<String,Object> map : maps){
            Integer type = (Integer) map.get("type");
            Long count = (Long) map.get("count");
            if(type != null && type == 1){
                result.put("courseWareCount",count);
            }else if(type != null && type == 2){
                result.put("handoutCount",count);
            }else if(type != null && type == 3){
                result.put("mediaCount",count);
            }else if(type != null && type == 4){
                result.put("otherCount",count);
            }else if(type != null && type == 5){
                result.put("teachplanCount",count);
            }else if(type != null && type == 6){
                result.put("multimediaCount",count);
            }
        }
        return result;
    }

    @Override
    public List<Material> queryMaterialByChapterId(String chapterId) {
        return this.dao.queryMaterialByChapterId(chapterId);
    }

    @Override
    @Transactional
    public Material saveMaterial(MaterialRequest bean, HttpServletRequest request) {
        Material material = new Material();
        BeanUtils.copyProperties(bean,material);
        material.setExt("html");
        this.dao.insert(material);

        if(!CollectionUtils.isEmpty(bean.getChapterId())){
            for (String chapterId : bean.getChapterId()) {
                MaterialChapter materialChapter = new MaterialChapter();
                materialChapter.setMaterialId(material.getId());
                materialChapter.setChapterId(chapterId);
                materialChapterService.insert(materialChapter);
            }
        }

        return material;
    }

    @Override
    public List queryChapterById(MaterialCourseIndexRequest bean) {
        List<BookChapter> chapters = new ArrayList<>();

        QueryWrapper<MaterialChapter> qw = new QueryWrapper();
        qw.eq("material_id",bean.getMaterialId());
        qw.orderByAsc("create_time");
        List<MaterialChapter> materialChapters = materialChapterService.queryByCondition(qw);
        if(!CollectionUtils.isEmpty(materialChapters)){
            for (MaterialChapter materialChapter : materialChapters) {
                BookChapter chapter = bookChapterService.getById(materialChapter.getChapterId());
                chapters.add(chapter);
            }
        }
        return chapters;
    }

    @Override
    public List<Material> queryUserPrivateMaterial(MaterialRequest bean) {
        return super.dao.queryUserPrivateMaterial(bean);
    }

    @Override
    public Material copyMaterial(MaterialRequest request) {
        Material material = this.getById(request.getId());
        if(null != material){
            Material newMaterial = new Material();
            BeanUtils.copyProperties(material,newMaterial);
            newMaterial.setId(null);
            this.insert(newMaterial);
            return newMaterial;
        }
        return null;
    }


    /**
     * 准备条件
     * @param bean
     * @param qw
     */
    private QueryWrapper<Material> prepareParams(MaterialRequest bean, QueryWrapper<Material> qw) {
        if(bean.getIds()!=null&&bean.getIds().length>0){
            qw.in("id",bean.getIds());
        }
        return qw;
    }

    /**
     * 文字转图片
     * @param title
     * @param filePath
     */
    private void textToPicture(String title, String filePath) {

        if(title == null || title.length() == 0) {
            return;
        }

        int width = 400;
        int height = 300;
        int size = 100;
        int fontHeight;
        int fontWidth;
        int lineNumber;
        int lines;
        int topPadding;
        int leftPadding;

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
        Graphics g = image.getGraphics();

        while (true) {
            // 必须要用等宽字体
            Font font = new Font("Consolas", Font.BOLD, size);
            FontMetrics fm = g.getFontMetrics(font);
            fontHeight = fm.getHeight();
            fontWidth = fm.stringWidth(title) / title.length();
            lineNumber = width / fontWidth; // 每行多少字
            lines = title.length() / lineNumber + 1; // 行数
            int fontsHeight = fontHeight * lines; // 字的总高度
            if(fontsHeight <= height) {
                topPadding = (height - fontsHeight) / 2;
                int fontsWidth = fontWidth * lineNumber; // 字的总宽度
                leftPadding = (width - fontsWidth) / 2;
                g.setFont(font);
                g.setColor(Color.red);
                break;
            }
            size--;
        }

        for(int i = 1;i<= lines; i++) {
            if(i == lines) {
                g.drawString(title.substring((i-1)*lineNumber),leftPadding, fontHeight * i + topPadding);
            }else {
                g.drawString(title.substring((i-1)*lineNumber, i * lineNumber),leftPadding, fontHeight * i + topPadding);

            }
        }

        try {
            ImageIO.write(image,"PNG",new FileOutputStream(filePath));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 下载讲义
     * @author 赵文博
     * @date 2021/5/11 16:58
     * @param materialId
     * @param request
     * @param fileType
     * @return void
     **/
    @Override
    public void downMaterial(String materialId, String fileType, Integer type,HttpServletResponse response, HttpServletRequest request) throws Exception {
        Material material = this.dao.selectById(materialId);

        if(material!=null){
            if(type == null){
                //默认学生卷
                type = 2;
            }
            String exportPath = MaterialUtils.exportMaterial(material,request,fileType,type);
            FileUtils.downloadLocalFile(material.getFileName(), exportPath, response);
        }
    }

    /**
     * 查询讲义 删除的也查出来
     * @author 赵文博
     * @date 2021/6/30 19:27
     * @param id
     * @return com.xh.bussiness.resource.model.Material
     **/
    @Override
    public Material queryMaterialById(String id) {
        return this.dao.queryMaterialById(id);
    }

    @Override
    public Object updateMaterial(HttpServletRequest request, Material material) {
        String rootPath = request.getSession().getServletContext().getRealPath("/");
        String relativePath="/upload"+"/";
        String customPath=request.getParameter("path");
        if(!StringUtils.isEmpty(customPath)){
            relativePath+=customPath+"/";
        }
        Date now =new Date();
        relativePath+= DateUtils.format(now,"yyyyMM")+"/";
        FileList fileList = new FileList();
        fileList.setFilePath(material.getFilePath());
        fileList.setExt(material.getExt());
        material.setImgPath(getFile2Png(fileList,rootPath,relativePath));
        super.update(material);
        return null;
    }
}
